#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#define ROWS 10
#define COLS 10
#define MINES 10

void print_board(char board[][COLS], int reveal);
int count_adjacent_mines(char board[][COLS], int row, int col);
void reveal_board(char board[][COLS], char mine_board[][COLS], int row, int col);
void mark_square(char board[][COLS], int row, int col, char mark);
int check_win(char board[][COLS], char mine_board[][COLS]);

int main() {
	char board[ROWS][COLS];
	char mine_board[ROWS][COLS];
	int row, col, remaining_squares, i, j, left_clicks = 0, marked_mines = 0;
	char click;

	// Initialize the game board and mine board
	for (i = 0; i < ROWS; i++) {
		for (j = 0; j < COLS; j++) {
			board[i][j] = '-';
			mine_board[i][j] = ' ';
		}
	}

	// Randomly place the mines on the mine board
	srand(time(NULL));
	for (i = 0; i < MINES; i++) {
		do {
			row = rand() % ROWS;
			col = rand() % COLS;
		} while (mine_board[row][col] == '*');
		mine_board[row][col] = '*';
	}

	// Play the game
	remaining_squares = ROWS * COLS - MINES;
	while (remaining_squares > 0) {
		print_board(board, 0);
		printf("Enter row, column, and click type (L, R, or M): ");
		scanf("%d %d %c", &row, &col, &click);

		if (click == 'L') {
			if (mine_board[row][col] == '*') {
				printf("Game over!\n");
				print_board(mine_board, 1);
				return 0;
			}
			else if (board[row][col] != '-') {
				printf("Square already revealed.\n");
			}
			else {
				if (count_adjacent_mines(mine_board, row, col) == 0) {
					reveal_board(board, mine_board, row, col);
				}
				else {
					board[row][col] = '0' + count_adjacent_mines(mine_board, row, col);
				}
				left_clicks++;
				remaining_squares--;
			}
		}
		else if (click == 'R') {
			if (board[row][col] == '-') {
				mark_square(board, row, col, '!');
				if (mine_board[row][col] == '*') {
					marked_mines++;
				}
			}
			else if (board[row][col] == '!') {
				mark_square(board, row, col, '?');
				if (mine_board[row][col] == '*') {
					marked_mines--;
				}
			}
			else if (board[row][col] == '?') {
				mark_square(board, row, col, '-');
			}
			else {
				printf("Square already revealed.\n");
			}
		}
		else if (click == 'M') {
			if (board[row][col] >= '1' && board[row][col] <= '8') {
				int num_marked_mines = 0, i, j;
				for (i = row - 1; i <= row + 1; i++) {
					for (j = col - 1; j <= col + 1; j++) {
						if (i >= 0 && i < ROWS && j >= 0 && j < COLS && board[i][j] == '!') {
							num_marked_mines++;
						}
					}
				}
				if (num_marked_mines == board[row][col] - '0') {
					int num_revealed_squares = 0;
					for (i = row - 1; i <= row + 1; i++) {
						for (j = col - 1; j <= col + 1; j++) {
							if (i >= 0 && i < ROWS && j >= 0 && j < COLS && board[i][j] == '-') {
								if (mine_board[i][j] == '*') {
									printf("Game over!\n");
									print_board(mine_board, 1);
									return 0;
								}
								else if (count_adjacent_mines(mine_board, i, j) == 0) {
									reveal_board(board, mine_board, i, j);
								}
								else {
									board[i][j] = '0' + count_adjacent_mines(mine_board, i, j);
								}
								num_revealed_squares++;
							}
						}
					}
					remaining_squares -= num_revealed_squares;
					left_clicks += num_revealed_squares;
				}
				else {
					printf("Incorrect number of marked mines.\n");
				}
			}
			else {
				printf("Square must have a number to use double click.\n");
			}
		}
		else {
			printf("Invalid click type.\n");
		}

		if (remaining_squares == 0) {
			printf("Congratulations, you won!\n");
			print_board(mine_board, 1);
			return 0;
		}

		printf("Left clicks: %d, Marked mines: %d\n", left_clicks, marked_mines);
	}

	return 0;
}

// Print the game board
void print_board(char board[][COLS], int reveal) {
	int i, j;

	printf("  ");
	for (i = 0; i < COLS; i++) {
		printf("%d ", i);
	}
	printf("\n");

	for (i = 0; i < ROWS; i++) {
		printf("%d ", i);
		for (j = 0; j < COLS; j++) {
			if (board[i][j] == '*' && reveal) {
				printf("* ");
			}
			else {
				printf("%c ", board[i][j]);
			}
		}
		printf("\n");
	}
}

// Count the number of adjacent mines to a square on the mine board
int count_adjacent_mines(char board[][COLS], int row, int col) {
	int count = 0, i, j;

	for (i = row - 1; i <= row + 1; i++) {
		for (j = col - 1; j <= col + 1; j++) {
			if (i >= 0 && i < ROWS && j >= 0 && j < COLS && board[i][j] == '*') {
				count++;
			}
		}
	}

	return count;
}

// Recursively reveal squares on the game board
void reveal_board(char board[][COLS], char mine_board[][COLS], int row, int col) {
	int adjacent_mines = count_adjacent_mines(mine_board, row, col);
	board[row][col] = '0' + adjacent_mines;

	if (adjacent_mines == 0) {
		int i, j;
		for (i = row - 1; i <= row + 1; i++) {
			for (j = col - 1; j <= col + 1; j++) {
				if (i >= 0 && i < ROWS && j >= 0 && j < COLS && board[i][j] == '-') {
					reveal_board(board, mine_board, i, j);
				}
			}
		}
	}
}

// Mark a square on the game board with a given mark
void mark_square(char board[][COLS], int row, int col, char mark) {
	board[row][col] = mark;
}

// Check if the player has won the game
int check_win(char board[][COLS], char mine_board[][COLS]) {
	int i, j;

	for (i = 0; i < ROWS; i++) {
		for (j = 0; j < COLS; j++) {
			if (board[i][j] == '-' && mine_board[i][j] != '*') {
				return 0;
			}
		}
	}

	return 1;
}